package com.gcxy.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gcxy.conf.result.PageVO;
import com.gcxy.conf.result.R;
import com.gcxy.conf.result.ResultCodeEnum;
import com.gcxy.dto.AccountInfoDto;
import com.gcxy.entity.AccountInfo;
import com.gcxy.mapper.AccountInfoMapper;
import com.gcxy.service.AccountInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gcxy.utils.JwtTokenUtil;
import com.gcxy.utils.Md5Utils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jiang
 * @since 2023-12-12
 */
@Service
public class AccountInfoServiceImpl extends ServiceImpl<AccountInfoMapper, AccountInfo> implements AccountInfoService {

    @Resource
    private RedisTemplate redisTemplate;

    private String PRE_ACC = "YZ";

    @Override
    public R addAccountInfo(AccountInfo accountInfo) {
        //验证电话号码是否唯一
        LambdaQueryWrapper<AccountInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(AccountInfo::getAccPhone, accountInfo.getAccPhone());
        AccountInfo accountPhone = this.baseMapper.selectOne(lqw);
        if (!ObjectUtils.isEmpty(accountPhone)) {
            return R.Failed(ResultCodeEnum.REQUEST_PARAM_ERROR.getCode(), "该电话号码已存在");
        }
        //验证用户名是否唯一
        LambdaQueryWrapper<AccountInfo> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(AccountInfo::getAccName, accountInfo.getAccName());
        AccountInfo accountName = this.baseMapper.selectOne(lqw1);
        if (!ObjectUtils.isEmpty(accountName)) {
            return R.Failed(ResultCodeEnum.REQUEST_PARAM_ERROR.getCode(), "该用户名已存在");
        }
        //生成账号
        //获取序号
        LambdaQueryWrapper<AccountInfo> lqw2 = new LambdaQueryWrapper<>();
        lqw2.orderByDesc(AccountInfo::getAccount).last("limit 1");
        //AccountInfo lastAccountInfo = this.baseMapper.selectOne(lqw);
        AccountInfo lastUser = getOne(lqw2);
        if (ObjectUtils.isEmpty(lastUser)) {
            //如果数据库没有 0001
            accountInfo.setAccount(PRE_ACC + "0001");
        } else {
            //如果数据库中有数据 拿最后一条数据的序号
            //最后一条数据账号
            String lastUserAccount = lastUser.getAccount();
            String idStr = lastUserAccount.substring(2, lastUserAccount.length());
            Integer id = Integer.valueOf(idStr) + 1;
            String formatId = String.format("%04d", id);
            String userAccount = PRE_ACC + (formatId);
            accountInfo.setAccount(userAccount);
        }
        //生成密码（取手机号后6位）
        //MD5加密密码
        String password = accountInfo.getAccPhone().substring(5,11);
        System.out.println(password);
        String passwordMd5 = Md5Utils.hash(password);
        accountInfo.setPassword(passwordMd5);

        this.baseMapper.insert(accountInfo);

        return R.Success(accountInfo);
    }

    @Override
    public Map<String, Object> login(AccountInfo accountInfo) {
        accountInfo.setAccPhone(accountInfo.getAccount());
        // 查询用户
        LambdaQueryWrapper<AccountInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(AccountInfo::getAccount, accountInfo.getAccount()).or()
                .eq(AccountInfo::getAccPhone, accountInfo.getAccPhone());
        AccountInfo loginUser = this.baseMapper.selectOne(lqw);
        // 结果不为空，则生成token
        if(loginUser != null){
            if (loginUser.getPassword().equals(Md5Utils.hash(accountInfo.getPassword()))) {
                // 生成token
                //String key = "user:" + UUID.randomUUID();
                String key = JwtTokenUtil.buildJwt(loginUser.getAccName(),loginUser.getAccount());
                // 将token存入redis中去
                loginUser.setPassword(null);
                redisTemplate.opsForValue().set(key, loginUser, 30, TimeUnit.MINUTES);
                // 返回数据
                System.out.println(loginUser);
                Map<String, Object> data = new HashMap<>();
                data.put("token", key);
                return data;
            }
        }
        // 结果为空登录失败
        return null;
    }

    @Override
    public Map<String, Object> current(String token) {
        System.out.println(JwtTokenUtil.verify(token));//判读token是否正确，写着玩玩
        System.out.println(JwtTokenUtil.getUsername(token));//获取用户名，写着玩玩
        System.out.println(JwtTokenUtil.getUserId(token));//获取用户id，写着玩玩
        // 根据token去redis中获取用户信息
        Object obj = redisTemplate.opsForValue().get(token);
        // 反序列化，变成user对象
        AccountInfo accountInfo = JSON.parseObject(JSON.toJSONString(obj), AccountInfo.class);
        System.out.println(accountInfo);
        if (accountInfo != null) {
            Map<String, Object> data = new HashMap<>();
            data.put("account", accountInfo.getAccount());
            data.put("accName", accountInfo.getAccName());
            data.put("accPhone", accountInfo.getAccPhone());
            data.put("isEnable", accountInfo.getIsEnable());
            data.put("createTime", accountInfo.getCreateTime());
            data.put("updateTime", accountInfo.getUpdateTime());
            return data;
        }
        return null;
    }

    @Override
    public void logout(String token) {
        System.out.println(redisTemplate.hasKey(token));//判断rides中是否还有该token,写着玩玩
        redisTemplate.delete(token);
        System.out.println(redisTemplate.hasKey(token));//判断rides中是否还有该token,写着玩玩
        System.out.println(JwtTokenUtil.verify(token));//判读token是否正确，写着玩玩
        System.out.println(JwtTokenUtil.getUsername(token));//获取用户名，写着玩玩
        System.out.println(JwtTokenUtil.getUserId(token));//获取用户id，写着玩玩
    }

    @Override
    public R<Page<AccountInfo>> getAccountInfoByPage(AccountInfoDto accountInfoDto) {
        LambdaQueryWrapper<AccountInfo> lqw = new LambdaQueryWrapper<>();
        //查询条件
        lqw.like(null != accountInfoDto.getAccName(), AccountInfo::getAccName, accountInfoDto.getAccName())
                .like(null != accountInfoDto.getAccPhone(), AccountInfo::getAccPhone, accountInfoDto.getAccPhone())
                .eq(null != accountInfoDto.getIsEnable(), AccountInfo::getIsEnable, accountInfoDto.getIsEnable());
        //分页对象
        Page<AccountInfo> accountInfoPage = new Page<>(accountInfoDto.getPageNumber(), accountInfoDto.getPageSize());
        //查询
        accountInfoPage = this.baseMapper.selectPage(accountInfoPage, lqw);

        PageVO<AccountInfo> accountInfoPageVO = new PageVO<>();
        BeanUtils.copyProperties(accountInfoPage, accountInfoPageVO);
        return R.Success(accountInfoPageVO);
    }

    @Override
    public R updateAccountInfo(AccountInfo accountInfo) {
        if (accountInfo.getAccount() == null || accountInfo.getAccount().length() == 0) {
            return R.Failed(ResultCodeEnum.INTERFACE_BASIC_INFORMATION_NULL.getCode(), "账号信息为空");
        }
        if (accountInfo.getAccPhone() != null) {
            //验证电话号码是否唯一
            LambdaQueryWrapper<AccountInfo> lqw = new LambdaQueryWrapper<>();
            lqw.eq(AccountInfo::getAccPhone, accountInfo.getAccPhone()).ne(AccountInfo::getAccount, accountInfo.getAccount());
            AccountInfo phoneUser = this.baseMapper.selectOne(lqw);
            if (!ObjectUtils.isEmpty(phoneUser)) {
                return R.Failed(ResultCodeEnum.REQUEST_PARAM_ERROR.getCode(), "该电话号码已存在");
            }
        }
        //MD5加密
        String password = Md5Utils.hash(accountInfo.getAccPhone().substring(5,11));
        accountInfo.setPassword(password);
        int row = this.baseMapper.updateById(accountInfo);
        if(row > 0){
            return R.Success("修改成功");
        }else{
            return R.Failed("修改失败");
        }

    }
}
